package cn.keniykey.mc.landterritory.landview;

import java.util.Collections;
import java.util.List;
import java.util.Set;

import javax.annotation.Nullable;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import cn.keniykey.mc.landterritory.config.ConfigurationManager;
import cn.keniykey.mc.landterritory.config.LanguageManager;
import cn.keniykey.mc.landterritory.config.ViewsConfiguration;
import cn.keniykey.mc.landterritory.config.ViewsConfiguration.ViewConfig;
import cn.keniykey.mc.landterritory.event.LandFlagUpdateEvent;
import cn.keniykey.mc.landterritory.land.api.Land;
import cn.keniykey.mc.landterritory.land.api.LandUtil;
import cn.keniykey.mc.landterritory.landflag.LandFlag;
import cn.keniykey.mc.landterritory.landflag.LandFlagManager;
import cn.keniykey.mc.landterritory.landflag.api.ELandFlagType;
import cn.keniykey.mc.landterritory.landflag.api.ILandFlagDetection;
import cn.keniykey.mc.landterritory.landflag.api.LandFlagSetting;
import cn.keniykey.mc.landterritory.toolkit.Util;
import cn.keniykey.mc.viewlibrary.container.api.EContainerType;
import cn.keniykey.mc.viewlibrary.view.api.AbFrameView;
import cn.keniykey.mc.viewlibrary.view.api.FrameViewBundle;
import cn.keniykey.mc.viewlibrary.view.api.IViewClickHandler;
import cn.keniykey.mc.viewlibrary.view.api.ViewClickReport;
import cn.keniykey.mc.viewlibrary.view.api.template.AbChooseView;
import cn.keniykey.mc.viewlibrary.view.api.template.ChooseViewIntentBuilder;

public final class LandFlagAddView extends AbLandFrameView{

	protected LandFlagAddView(Player player1) {
		super(player1);
	}
	
	private static final String VIEW_NAME = "addflag";
	private static final int CODE_CHOOSE_ADD = 10500;
	
	private Land land;
	private List<LandFlag> list_flags;
	private ELandFlagType flagtype_show;
	private int page = 1,page_max;
	
	@Override
	protected void onCreate() {
		super.onCreate();
		
		final FrameViewBundle bundle = this.getIntent().getExtras();
		this.land = bundle.getValue("land", null);
		
		final ViewConfig config_view = ViewsConfiguration.getViewConfig(VIEW_NAME);
		this.setViewType(EContainerType.GENERIC_6X9);
		
		this.setIconClick(49, config_view.getViewItem("back"), AbLandFrameView.CLICK_BACK);
		this.setIconClick(45, config_view.getViewItem("first"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(LandFlagAddView.this.page < 2) return;
				if(!LandFlagAddView.this.isMatchClickSpeed()) return;
				LandFlagAddView.this.page = 1;
				LandFlagAddView.this.refreshPage();
			}
		});
		this.setIconClick(47, config_view.getViewItem("last"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(LandFlagAddView.this.page < 2) return;
				if(!LandFlagAddView.this.isMatchClickSpeed()) return;
				LandFlagAddView.this.page--;
				LandFlagAddView.this.refreshPage();
			}
		});
		this.setIconClick(51, config_view.getViewItem("next"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(LandFlagAddView.this.page >= LandFlagAddView.this.page_max) return;
				if(!LandFlagAddView.this.isMatchClickSpeed()) return;
				LandFlagAddView.this.page++;
				LandFlagAddView.this.refreshPage();
			}
		});
		this.setIconClick(53, config_view.getViewItem("end"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(LandFlagAddView.this.page >= LandFlagAddView.this.page_max) return;
				if(!LandFlagAddView.this.isMatchClickSpeed()) return;
				LandFlagAddView.this.page = LandFlagAddView.this.page_max;
				LandFlagAddView.this.refreshPage();
			}
		});
		this.setIconClick(38, config_view.getViewItem("player"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(ELandFlagType.PLAYER.equals(LandFlagAddView.this.flagtype_show)) return;
				if(!LandFlagAddView.this.isMatchClickSpeed()) return;
				LandFlagAddView.this.refreshShowType(ELandFlagType.PLAYER);
			}
		});
		this.setIconClick(40, config_view.getViewItem("special"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(ELandFlagType.SPECIAL.equals(LandFlagAddView.this.flagtype_show)) return;
				if(!LandFlagAddView.this.isMatchClickSpeed()) return;
				LandFlagAddView.this.refreshShowType(ELandFlagType.SPECIAL);
			}
		});
		this.setIconClick(42, config_view.getViewItem("admin"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(ELandFlagType.ADMIN.equals(LandFlagAddView.this.flagtype_show)) return;
				if(!LandFlagAddView.this.isMatchClickSpeed()) return;
				LandFlagAddView.this.refreshShowType(ELandFlagType.ADMIN);
			}
		});
	}
	
	@Override
	protected void onShowBefore() {
		if(this.flagtype_show == null) {
			this.refreshShowType(ELandFlagType.PLAYER);
			return;
		}
		this.refreshPage();
	}
	
	private void refreshShowType(ELandFlagType type) {
		this.flagtype_show = type;
		this.list_flags = Collections.unmodifiableList(LandFlagManager.getFlagManager().getLandFlags(type));
		this.page_max = ((this.list_flags.size() / 36) + 1);
		this.page = 1;
		this.refreshPage();
	}
	private void refreshPage() {
		if(this.page < 1) this.page = 1;
		if(this.page > this.page_max) this.page = this.page_max;
		for(int index = 0; index < 36; index++) this.getContainer().setItemStack(index, null, false);
		this.clearIconsClick(0, 35);
		final IViewClickHandler handler = new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(!report.isLeftClick() || !LandFlagAddView.this.isMatchClickSpeed()) return;
				final int row = this.getPageIndex(report.getClickRawSlot());
				if(row >= LandFlagAddView.this.list_flags.size()) return;
				final LandFlag flag = LandFlagAddView.this.list_flags.get(row);
				final ChooseViewIntentBuilder builder = new ChooseViewIntentBuilder(LandChooseView.class);
				builder.setChooseCountdown(ConfigurationManager.View_Choose_Countdown);
				builder.setCustomPromptName(LanguageManager.getLang(1105104));
				builder.setCustomPromptLore(Util.listFromStr(LanguageManager.getLang(1105105,
						LandViewUtil.getLandLabelStr(LandFlagAddView.this.land), flag.getDisplayName())));
				builder.setForwardContent(flag);
				LandFlagAddView.this.showViewForResult(builder.build(), CODE_CHOOSE_ADD);
			}
			private int getPageIndex(int row) {
				return (((LandFlagAddView.this.page - 1) * 36) + row);
			}
		};
		final int begin_flag_index = ((this.page - 1) * 36);
		final ViewConfig config_view = ViewsConfiguration.getViewConfig(VIEW_NAME);
		final ItemStack item_backup = config_view.getViewItem("about");
		for(int index = 0,flag_index = begin_flag_index, flag_max_index = this.list_flags.size();
				flag_index < flag_max_index && index < 36; index++,flag_index++) {
			final LandFlag landflag = this.list_flags.get(flag_index);
			if(this.land.getFlags().containsKey(landflag.getName())) continue;
			this.getContainer().setItemStack(index, this.getLandFlagInfoItemStack(item_backup, landflag), false);
			this.setIconClick(index, handler);
		}
		this.setTitle(Util.conver(Util.setStr(config_view.getViewTitle(), this.page, this.page_max)));
	}
	private ItemStack getLandFlagInfoItemStack(ItemStack item_backup, LandFlag landflag) {
		final ItemStack item = item_backup.clone();
		final ItemMeta meta = item.getItemMeta();
		meta.setDisplayName(meta.getDisplayName() + landflag.getDisplayName());
		final StringBuilder builder_str = new StringBuilder();
		builder_str.append(LanguageManager.getLang(1105106)).append("\n");
		builder_str.append(LanguageManager.getLang(1102000, landflag.getName(),
				LanguageManager.getLang(landflag.getELandFlagParType().getLandID())));
		final List<String> indulist = landflag.getIntroductionLore();
		if(indulist != null && !indulist.isEmpty()) {
			builder_str.append("\n").append(LanguageManager.getLang(1102001));
			for(final String str_indu : indulist) {
				builder_str.append("\n ").append(str_indu);
			}
		}
		meta.setLore(Util.listFromStr(builder_str.toString()));
		item.setItemMeta(meta);
		return item;
	}
	
	@Override
	protected void onViewResult(int requestcode, int resultcode, @Nullable FrameViewBundle bundle) {
		super.onViewResult(requestcode, resultcode, bundle);
		switch(AbChooseView.EChooseResult.muchResult(resultcode)) {
		case CONFIRM:
			if(CODE_CHOOSE_ADD == requestcode) {
				addLandFlag(bundle.getValue(AbChooseView.EChooseResultIntentKey.FORWARD.toString(), null));
				return;
			}
			this.getPlayer().sendMessage(LanguageManager.getChatLang(1001001) + requestcode);
			break;
		case VETO: return;
		default:
		}
		this.finishAll();
	}
	
	private void addLandFlag(LandFlag flag) {
		final Player player = this.getPlayer();
		if(!LandUtil.hasLandPermission(player, this.land, LandViewUtil.getLandFLagMinPermissionLevel(flag))) {
			player.sendMessage(LanguageManager.getChatLang(1105100, LandViewUtil.getLandLabelStr(this.land), 
					flag.getDisplayName()));
			return;
		}
		
		final Set<String> flags_conflict = flag.getDescription().getConflictFlag();
		for(final String flagname : flags_conflict) {
			final LandFlag flag_check = LandFlagManager.getFlagManager().getLandFlag(flagname);
			if(flag_check == null || !this.land.getFlags().containsKey(flagname)) continue;
			player.sendMessage(LanguageManager.getChatLang(1105102, flag.getDisplayName(), LandViewUtil.getLandLabelStr(this.land),
					flag_check.getDisplayName()));
			return;
		}//先判断本标记的冲突
		final String flagname = flag.getName();
		for(final LandFlag flag_check : LandFlagManager.getFlagManager().getLandFlags()) {
			if(!flag_check.getDescription().getConflictFlag().contains(flagname) ||
					!this.land.getFlags().containsKey(flag_check.getName())) continue; //如果本标记不在遍历标记的冲突名单中，或领地没有此遍历标记，跳过
			player.sendMessage(LanguageManager.getChatLang(1105102, flag.getDisplayName(), LandViewUtil.getLandLabelStr(this.land),
					flag_check.getDisplayName()));
			return;
		}//后判断服务器已加载的标记
		
		if(!this.land.getFlags().containsKey(flagname)) {
			final ILandFlagDetection dete_add = LandFlagSetting.getAddDetection(flagname);
			if(dete_add != null) {
				try {
					if(!dete_add.onRequest(player, this.land)) {
						player.sendMessage(LanguageManager.getChatLang(1105101, LandViewUtil.getLandLabelStr(this.land),
								flag.getDisplayName()));
						return;
					}
				}catch(Exception ex) {
					ex.printStackTrace();
				}
			}
			this.land.getFlags().put(flagname, Collections.emptySet());
			this.land.updateFlags();
			Bukkit.getPluginManager().callEvent(new LandFlagUpdateEvent(player, this.land, flag));
		}
		player.sendMessage(LanguageManager.getChatLang(1105103, flag.getDisplayName(), LandViewUtil.getLandLabelStr(this.land)));
	}
}